﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.ComponentModel;

namespace RelatorioDinamico.Domain.Util
{
    public class RelatorioDinamico
    {
        public string @Namespace { get; set; }

        public RelatorioDinamico()
        {
            @Namespace = "RelatorioDinamico.Domain";
        }

        public RelatorioDinamico(string @namespace)
        {
            @Namespace = @namespace;
        }

        public Dictionary<string, string> SelecionarTabelasDinamicas(string tabelaBase = null)
        {
            if (tabelaBase == null) return SelecionarTodasTabelas();

            return null;
        }

        public Dictionary<string, string> SelecionarTodasTabelas()
        {
            return Assembly.GetExecutingAssembly().GetTypes()
                .Where(t => String.Equals(t.Namespace, @Namespace, StringComparison.Ordinal) && t.IsClass)
                .ToDictionary(t => t.FullName, PreencherNome)
                .OrderBy(d => d.Value).ToDictionary(t => t.Key, t => t.Value);
        }

        private List<PropertyInfo> SelecionarColunas(string tabela)
        {
            return Type.GetType(tabela).GetProperties().ToList();
        }

        public List<string> SelecionarColunasPrimitivas(string tabela)
        {
            return SelecionarColunas(tabela).Where(t => !t.PropertyType.Namespace.Contains(@Namespace)).Select(PreencherNome).ToList();
        }

        public Dictionary<string, string> SelecionarColunasReferencias(string tabela)
        {
            return SelecionarColunas(tabela).Where(t => t.PropertyType.Namespace.Contains(@Namespace))
                .ToDictionary(t => t.PropertyType.FullName, PreencherNome);
        }

        private string PreencherNome(PropertyInfo propertyInfo)
        {
            var attributes = propertyInfo.GetCustomAttributes(typeof(DescriptionAttribute), false).ToList();
            return attributes.Any() ? ((DescriptionAttribute)attributes.First()).Description : propertyInfo.Name;
        }

        private string PreencherNome(Type type)
        {
            var attributes = type.GetCustomAttributes(typeof(DescriptionAttribute), false).ToList();
            return attributes.Any() ? ((DescriptionAttribute)attributes.First()).Description : type.Name;
        }
    }
}